package com.aizhixin.lab.account.service;

import com.aizhixin.lab.account.domain.ZhiXinUserDomain;
import com.aizhixin.lab.account.dto.AccountDTO;
import com.aizhixin.lab.account.dto.ZXAccountDTO;
import com.aizhixin.lab.account.dto.ZXAccountResultDTO;
import com.aizhixin.lab.common.core.DataValidity;
import com.aizhixin.lab.company.entity.User;
import com.aizhixin.lab.company.repository.UserRepository;
import com.aizhixin.lab.config.Config;
import com.aizhixin.lab.remote.ZhixinClient;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Charsets;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.net.URLEncoder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@SuppressWarnings("unchecked")
public class AccountService {
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private Config config;
    @Autowired
    private ZhixinClient zhixinClient;
    
    private String TYPE_TOKEN = "token:";

    public AccountDTO getUserByToken(String token) {
        AccountDTO dto = getAccountDTOFromRedis(token);
        if (dto == null) {
            return null;
//            dto = getAccountDTO(token);
//            if (dto != null) {
//                setRedisAccountDTO(token, dto);
//            }
        }
        return dto;
    }

    public void clearOnToken(Long id){
        User one = userRepository.findOne(id);
        one.setOntoken(null);
        userRepository.save(one);
    }
    public void saveOnToken(Long id,String token){
        User one = userRepository.findOne(id);
        one.setOntoken(token);
        userRepository.save(one);
    }
//    public AccountDTO getZXUserByToken(String token) {
//        AccountDTO dto = getAccountDTOFromRedis(token);
//        if (dto == null) {
//            dto = getZXAccountDTO(token);
//            if (dto != null) {
//                setRedisAccountDTO(token, dto);
//            }
//        }
//        return dto;
//    }

    private AccountDTO getAccountDTOFromRedis(String token) {
        String str = (String) redisTemplate.opsForValue().get(token);
        if (!StringUtils.isEmpty(str)) {
            return JSON.parseObject(str, AccountDTO.class);
        }
        return null;
    }

    private AccountDTO getAccountDTOByKey(String key) {
        try {
            String str = (String) redisTemplate.opsForValue().get(key);
            if (!StringUtils.isEmpty(str)) {
                return JSON.parseObject(str, AccountDTO.class);
            }
        } catch (Exception e) {
            log.warn("Exception", e);
        }
        return null;
    }

    private void setRedisAccountDTO(String token, AccountDTO dto) {
        String str = JSON.toJSONString(dto);
        redisTemplate.opsForValue().set(TYPE_TOKEN + token.replace("Bearer ", ""), str, 1, TimeUnit.DAYS);
    }

    public void delRedisAccountDTO(Long accountId) {
        Set<String> keys = redisTemplate.keys(TYPE_TOKEN + "*");
        if (keys != null && keys.size() > 0) {
            for (String key : keys) {
                AccountDTO dto = getAccountDTOByKey(key);
                if (dto != null && dto.getAccountId() != null && dto.getAccountId().longValue() == accountId.longValue()) {
                    redisTemplate.delete(key);
                    break;
                }
            }
        }
    }

    private AccountDTO getAccountDTO(String token) {
        ZhiXinUserDomain domain = zhixinClient.getZXUser(token);
        return typeAccountDTO(domain);
    }

//    private AccountDTO getZXAccountDTO(String token) {
//        ZhiXinUserDomain domain = zhixinClient.getZXUser(token);
//        return typeZXAccountDTO(domain);
//    }


    private AccountDTO typeAccountDTO(ZhiXinUserDomain domain) {
        if (domain != null) {
            User user = userRepository.findByAccountId(domain.getId());
            if (user != null) {
                AccountDTO dto = new AccountDTO();
                BeanUtils.copyProperties(user, dto);
                return dto;
            }
        }
        return null;
    }

//    private AccountDTO typeZXAccountDTO(ZhiXinUserDomain domain) {
//        if (domain != null) {
//            AccountDTO dto = new AccountDTO();
//            dto.setId(domain.getId());
//            dto.setAccountId(domain.getId());
//            dto.setUserName(domain.getLogin());
//            dto.setName(domain.getUserName());
//            dto.setRole(domain.getRoleGroup());
//            return dto;
//        }
//        return null;
//    }

    public Long addZXAccount(AccountDTO user) {
        try {
            ZXAccountDTO dto = new ZXAccountDTO(user.getUserName(), user.getName(), "B",user.getPassword());//dlEduFileSystem
            return postAddZXAccount(dto);
        } catch (Exception e) {
            log.warn("Exception", e);
        }
        return null;
    }

    public Long postAddZXAccount(ZXAccountDTO dto) {
        RestTemplate restTemplate = new RestTemplate();
        try {
        	if(StringUtils.isEmpty(dto.getPassword())) {
        		dto.setPassword("dingli123");
        	}
            Map<String, Object> map = new HashMap<>();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<Map<String, Object>> request = new HttpEntity<>(map, headers);
            String queryPath = config.getZhiXinApiPath() + config.getZhiXinApiAddUser() + "?";
            queryPath += "loginName=" + dto.getLoginName();
            queryPath += "&name=" + dto.getName();
            queryPath += "&password=" + dto.getPassword();
            queryPath += "&userType=" + dto.getUserType();

            System.out.println(queryPath);
            System.out.println(queryPath);


            ResponseEntity<String> response = restTemplate.postForEntity(queryPath, request, String.class);
            log.info(response.getBody());
            ZXAccountResultDTO resultDTO = JSON.parseObject(response.getBody(), ZXAccountResultDTO.class);
            if (resultDTO != null) {
                return resultDTO.getId();
            }
        } catch (Exception e) {
            log.warn("Exception", e);
        }
        return null;
    }

    public boolean deleteZXAccount(User user) {
        RestTemplate restTemplate = new RestTemplate();
        try {
            String queryPath = config.getZhiXinApiPath() + config.getZhiXinApiDeleteUser() + user.getAccountId();
            restTemplate.delete(queryPath);
            return true;
        } catch (Exception e) {
            log.warn("Exception", e);
            return false;
        }
    }

    public boolean updatePassword(User user, String password) {
        RestTemplate restTemplate = new RestTemplate();
        try {
            Map<String, Object> map = new HashMap<>();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<Map<String, Object>> request = new HttpEntity<>(map, headers);
            String queryPath = config.getZhiXinApiPath() + config.getZhiXinApiUpdatePassword() + "?id=" + user.getAccountId() + "&password=" + password;
            ResponseEntity<String> response = restTemplate.postForEntity(queryPath, request, String.class);
            return true;
        } catch (Exception e) {
            log.warn("Exception", e);
        }
        return false;
    }

    public boolean checkOldPassword(User user, String password) {
        RestTemplate restTemplate = new RestTemplate();
        try {
            String plainClientCredentials = "dleduApp:mySecretOAuthSecret";
            String base64ClientCredentials = new String(Base64.encodeBase64(plainClientCredentials.getBytes()));
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
            headers.set("Authorization", "Basic " + base64ClientCredentials);
            String pp = "username=" + URLEncoder.encode(user.getUserName(), Charsets.UTF_8.name()) + "&password=" + URLEncoder.encode(password, Charsets.UTF_8.name()) + "&grant_type=password&scope=read%20write&client_secret=mySecretOAuthSecret&client_id=dleduApp";
            HttpEntity<String> request = new HttpEntity<>(pp, headers);
            String queryPath = config.getZhiXinApiPath() + config.getZhiXinApiOauthToken();
            log.info("queryPath: {}", queryPath);
            log.info("params: {}", pp);
            ResponseEntity<String> response = restTemplate.postForEntity(queryPath, request, String.class);
            if (response.getStatusCode() == HttpStatus.OK) {
                if (response.getBody().indexOf("access_token") > 0) {
                    return true;
                }
            }
        } catch (Exception e) {
            log.warn("Exception", e);
        }
        return false;
    }
}
